首页 > 应用开发 > Java > 从头到尾说一次 Spring 事务管理(器)
来源:京东云开发者
// MethodA:public void methodA(){Connection connection = acquireConnection();try{int updated = connection.prepareStatement().executeUpdate();methodB(connection);connection.commit();}catch (Exception e){rollback(connection);}finally {releaseConnection(connection);}}// MethodB:public void methodB(Connection connection){int updated = connection.prepareStatement().executeUpdate();}
static ThreadLocal<Connection> connHolder = new ThreadLocal<>();// MethodA:public void methodA(){Connection connection = acquireConnection();connHolder.set(connection);try{int updated = connection.prepareStatement().executeUpdate();methodB();connection.commit();}catch (Exception e){rollback(connection);}finally {releaseConnection(connection);connHolder.remove();}}// MethodB:public void methodB(){Connection connection = connHolder.get();int updated = connection.prepareStatement().executeUpdate();}
static ThreadLocal<Connection> connHolder = new ThreadLocal<>();private void bindConnection(){Connection connection = acquireConnection();connHolder.set(connection);}private void unbindConnection(){releaseConnection(connection);connHolder.remove();}// MethodA:public void methodA(){try{bindConnection();int updated = connection.prepareStatement().executeUpdate();methoB();connection.commit();}catch (Exception e){rollback(connection);}finally {unbindConnection();}}// MethodB:public void methodB(){Connection connection = connHolder.get();int updated = connection.prepareStatement().executeUpdate();}
// MethodA:public void methodA(){int updated = connection.prepareStatement().executeUpdate();methodB();// ...}// MethodB:public void methodB(){// ...}
@Transactionalpublic void methodA(){jdbcTemplate.batchUpdate(updateSql, params);methodB();}@Transactionalpublic void methodB(){jdbcTemplate.batchUpdate(updateSql, params);}
@Transactionalpublic void methodA(){jdbcTemplate.batchUpdate(updateSql, params);methodB();}// 传播行为配置为 - 方式2,不使用当前事务,独立一个新事务@Transactional(propagation = Propagation.REQUIRES_NEW)public void methodB(){jdbcTemplate.batchUpdate(updateSql, params);}
// 传播行为配置为 - 方式2,不使用当前事务,独立一个新事务// 指定 Exception 也不会滚@Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = Exception.class)public void methodB(){jdbcTemplate.batchUpdate(updateSql, params);}
@Transactionalpublic void methodA(){jdbcTemplate.batchUpdate(updateSql, params);methodB();}// 传播行为配置为 - 方式2,不使用当前事务,独立一个新事务// 这个事务/连接中使用 RC 隔离级别,而不是默认的 RR@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)public void methodB(){jdbcTemplate.batchUpdate(updateSql, params);}
interface PlatformTransactionManager{ // 获取事务资源,资源可以是任意的,比如jdbc connection/hibernate mybatis session之类 TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; // 提交事务 void commit(TransactionStatus status) throws TransactionException; // 回滚事务 void rollback(TransactionStatus status) throws TransactionException;}public final TransactionStatus getTransaction(TransactionDefinition definition) { //创建事务资源 - 比如 Connection Object transaction = doGetTransaction(); if (isExistingTransaction(transaction)) { // 处理当前已有事务的场景 return handleExistingTransaction(def, transaction, debugEnabled); }else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED){ // 开启新事务 return startTransaction(def, transaction, debugEnabled, suspendedResources); }else { // 彻底不用事务 } // ...}private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled, SuspendedResourcesHolder suspendedResources) { // 创建事务 DefaultTransactionStatus status = newTransactionStatus( definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); // 开启事务(beginTx或者setAutoCommit之类的操作) // 然后将事务资源绑定到事务资源管理器 TransactionSynchronizationManager doBegin(transaction, definition);


这里再解释下,为什么新事务才需要提交,而已经有事务却什么都不用做:
public Object invoke(MethodInvocation invocation) throws Throwable { // 获取事务资源 Object transaction = transactionManager.getTransaction(txAttr); Object retVal; try { // 执行业务代码 retVal = invocation.proceedWithInvocation(); // 提交事务 transactionManager.commit(txStatus); } catch (Throwable ex){ // 先判断异常回滚策略,然后调用事务管理器的 rollback rollbackOn(ex, txStatus); } }public <T> T execute(TransactionCallback<T> action) throws TransactionException { // 获取事务资源 TransactionStatus status = this.transactionManager.getTransaction(this); T result; try { // 执行 callback 业务代码 result = action.doInTransaction(status); } catch (Throwable ex) { // 调用事务管理器的 rollback rollbackOnException(status, ex); } 提交事务 this.transactionManager.commit(status); }}
Integer rows = new TransactionTemplate((PlatformTransactionManager) transactionManager,new DefaultTransactionDefinition(TransactionDefinition.ISOLATION_READ_UNCOMMITTED)).execute(new TransactionCallback<Integer>() {public Integer doInTransaction(TransactionStatus status) {// update 0int rows0 = jdbcTemplate.update(...);// update 1int rows1 = jdbcTemplate.update(...);return rows0 + rows1;}});Integer rows2 = new TransactionTemplate((PlatformTransactionManager) transactionManager,new DefaultTransactionDefinition(TransactionDefinition.ISOLATION_READ_UNCOMMITTED)).execute(new TransactionCallback<Integer>() {public Integer doInTransaction(TransactionStatus status) {// update 2int rows2 = jdbcTemplate.update(...);return rows2;}});
@Transactionalpublic void methodA(){ // update 1 jdbcTemplate.update(...); new TransactionTemplate((PlatformTransactionManager) transactionManager, new DefaultTransactionDefinition(TransactionDefinition.ISOLATION_READ_UNCOMMITTED)) .execute(new TransactionCallback<Integer>() { @Override public Integer doInTransaction(TransactionStatus status) { // update 2 int rows2 = jdbcTemplate.update(...); return rows2; } }); }
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70024922/viewspace-2980084/ ,如需转载,请注明出处,否则将追究法律责任。