중요 개념
자동 커밋 모드
mysql 데이터베이스의 경우 기본적으로 데이터베이스는 자동 커밋 모드입니다. 각 문은 별도의 트랜잭션에 있습니다. 문이 실행될 때 실행이 성공하면 트랜잭션이 암시적으로 커밋되고, 실행이 실패하면 트랜잭션이 암시적으로 롤백됩니다. 일반적인 트랜잭션 관리를 위해서는 관련 작업들의 그룹이 하나의 트랜잭션에 있으므로 데이터베이스의 자동 제출 모드를 꺼야 합니다. 이를 보는 방법은 다음과 같습니다.
명령이 자동으로 제출되는지 확인합니다. (ON은 자동 제출을 의미합니다. 켜져 있으면 값이 1이고, 꺼지면 자동 제출이 꺼진 것을 의미하며 값은 0입니다.):
show variables like 'autocommit';
자동 제출을 끈 후에도 사용자는 커밋 또는 롤백 문이 실행되어 트랜잭션을 종료할 때까지 항상 트랜잭션에 남아 있습니다. 현재 트랜잭션을 종료하고 새 트랜잭션을 시작합니다.
DataSource connection = masterDataSource.getConnection(); connection.setAutoCommit(false);
트랜잭션 격리 수준
격리 수준은 여러 동시 트랜잭션 간의 격리 정도를 나타냅니다. TransactionDefinition 인터페이스는 격리 수준을 나타내는 5개의 상수를 정의합니다:
1. TransactionDefinition.ISOLATION_DEFAULT
: 이는 기본 데이터베이스의 기본 격리 수준이 사용됨을 나타내는 기본값입니다. 대부분의 데이터베이스에서 이 값은 일반적으로 TransactionDefinition.ISOLATION_READ_COMMITTED
입니다. TransactionDefinition.ISOLATION_DEFAULT
:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED
。
2、TransactionDefinition.ISOLATION_READ_UNCOMMITTED
:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读,不可重复读和幻读,因此很少使用该隔离级别。比如PostgreSQL实际上并没有此级别。
3、TransactionDefinition.ISOLATION_READ_COMMITTED
:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。
4、TransactionDefinition.ISOLATION_REPEATABLE_READ
:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。该级别可以防止脏读和不可重复读。
5、TransactionDefinition.ISOLATION_SERIALIZABLE
:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
事务传播行为
所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:
1、TransactionDefinition.PROPAGATION_REQUIRED
:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
2、TransactionDefinition.PROPAGATION_REQUIRES_NEW
:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
3、TransactionDefinition.PROPAGATION_SUPPORTS
:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
4、TransactionDefinition.PROPAGATION_NOT_SUPPORTED
:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
5、TransactionDefinition.PROPAGATION_NEVER
:以非事务方式运行,如果当前存在事务,则抛出异常。
6、TransactionDefinition.PROPAGATION_MANDATORY
:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
7、TransactionDefinition.PROPAGATION_NESTED
:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED
。
保护点(Savepoints
2. TransactionDefinition.ISOLATION_READ_UNCOMMITTED
: 이 격리 수준은 트랜잭션이 다른 트랜잭션에 의해 수정되었지만 아직 커밋되지 않은 데이터를 읽을 수 있음을 나타냅니다. 이 수준은 더티 읽기, 반복 불가능 읽기 및 팬텀 읽기를 방지하지 않으므로 이 격리 수준은 거의 사용되지 않습니다. 예를 들어 PostgreSQL에는 실제로 이 수준이 없습니다.
3. TransactionDefinition.ISOLATION_READ_COMMITTED
: 이 격리 수준은 트랜잭션이 다른 트랜잭션에 의해 제출된 데이터만 읽을 수 있음을 의미합니다. 이 수준은 더티 읽기를 방지하며 대부분의 경우 권장되는 값입니다.
4. TransactionDefinition.ISOLATION_REPEATABLE_READ
: 이 격리 수준은 트랜잭션이 전체 프로세스에서 쿼리를 여러 번 반복적으로 실행할 수 있으며 매번 반환되는 레코드가 동일함을 의미합니다. 이 수준은 더티 읽기(dirty read) 및 반복 불가능한 읽기를 방지합니다.
5. TransactionDefinition.ISOLATION_SERIALIZABLE
: 모든 트랜잭션이 하나씩 실행되므로 트랜잭션 간 간섭 가능성이 없습니다. 즉, 이 수준에서는 더티 읽기(dirty read), 반복 불가능한 읽기 및 읽기를 방지할 수 있습니다. 팬텀이 읽습니다. 그러나 이는 프로그램 성능에 심각한 영향을 미칩니다. 일반적으로 이 수준은 사용되지 않습니다.
소위 트랜잭션 전파 동작은 현재 트랜잭션을 시작하기 전에 트랜잭션 컨텍스트가 이미 존재하는 경우 트랜잭션 메서드의 실행 동작을 지정하는 여러 옵션이 있음을 의미합니다. TransactionDefinition 정의에는 전파 동작을 나타내는 다음 상수가 포함됩니다.
1. TransactionDefinition.PROPAGATION_REQUIRED
: 현재 트랜잭션이 있으면 트랜잭션에 참여하고, 현재 트랜잭션이 없으면 새 트랜잭션을 만듭니다. 이것이 기본값입니다. 2. TransactionDefinition.PROPAGATION_REQUIRES_NEW
: 현재 트랜잭션이 존재하는 경우 현재 트랜잭션을 일시 중지합니다.
3. TransactionDefinition.PROPAGATION_SUPPORTS
: 현재 트랜잭션이 있으면 트랜잭션에 참여하고, 현재 트랜잭션이 없으면 비트랜잭션 방식으로 계속 실행합니다.
TransactionDefinition.PROPAGATION_NOT_SUPPORTED
: 트랜잭션이 현재 존재하는 경우 현재 트랜잭션이 일시 중지됩니다. 5. TransactionDefinition.PROPAGATION_NEVER
: 트랜잭션이 현재 존재하는 경우 예외가 발생합니다.
TransactionDefinition.PROPAGATION_MANDATORY
: 현재 트랜잭션이 있으면 트랜잭션에 참여하고, 현재 트랜잭션이 없으면 예외를 발생시킵니다. 🎜🎜7. TransactionDefinition.PROPAGATION_NESTED
: 현재 트랜잭션이 있는 경우 현재 트랜잭션의 중첩 트랜잭션으로 실행할 트랜잭션을 생성합니다. >TransactionDefinition .PROPAGATION_REQUIRED. 🎜🎜🎜Safepoint(Savepoints
)🎜🎜🎜우선 저장점은 롤백을 위한 것임을 알아야 합니다. 저장점 수에는 제한이 없습니다. 거래의 한 지점입니다. 거래의 일부를 취소하는 데 사용됩니다. 거래가 종료되면 거래에 정의된 모든 저장 포인트가 자동으로 삭제됩니다. 🎜🎜롤백 실행 시 저장 지점을 지정하여 지정된 지점으로 롤백할 수 있습니다. 🎜🎜트랜잭션 롤백을 위한 몇 가지 중요한 작업 🎜🎜1. 저장 지점 a를 설정합니다. 🎜🎜2. 저장 지점 a 이후로 트랜잭션 롤백을 취소합니다. 🎜🎜3. 모든 트랜잭션 롤백을 취소합니다. transaction, 커밋하기 전에 사용해야 합니다. 🎜🎜public class UserRepository { private DataSource masterDataSource; private Connection connection = null; @Autowired public void setMasterDataSource(DataSource masterDataSource) { this.masterDataSource = masterDataSource; } @Transactional public boolean save(User user) { try { connection = masterDataSource.getConnection(); connection.setAutoCommit(false); //设置保护点 Savepoint saveUser = connection.setSavepoint("saveUser"); PreparedStatement prepareStatement = connection.prepareStatement("insert into user(id,name,age) values(?,?,?)"); prepareStatement.setLong(1, user.getId()); prepareStatement.setString(2, user.getName()); prepareStatement.setInt(3, user.getAge()); prepareStatement.execute(); try { update(user); } catch (Exception e) { System.out.println("出错了。。"+e); //回滚至保护点 connection.rollback(saveUser); } connection.commit(); } catch (SQLException e) { e.printStackTrace(); } finally { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } return true; } public boolean update(User user) { System.out.println("save user:"+user); try { PreparedStatement prepareStatement = connection.prepareStatement("update user set name = ? ,age = ? where id = ?)"); prepareStatement.setLong(3, user.getId()); prepareStatement.setString(1, "王大拿"); prepareStatement.setInt(2, 100/0); prepareStatement.execute(); connection.commit(); } catch (SQLException e) { e.printStackTrace(); } return true; } }
위 내용은 SpringBoot 트랜잭션에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!