// 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(){
// ...
}
@Transactional
public void methodA(){
jdbcTemplate.batchUpdate(updateSql, params);
methodB();
}
@Transactional
public void methodB(){
jdbcTemplate.batchUpdate(updateSql, params);
}
@Transactional
public 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);
}
@Transactional
public 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 0
int rows0 = jdbcTemplate.update(...);
// update 1
int 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 2
int rows2 = jdbcTemplate.update(...);
return rows2;
}
});
public void methodA(){
// update 1
jdbcTemplate.update(...);
new TransactionTemplate((PlatformTransactionManager) transactionManager,
new DefaultTransactionDefinition(TransactionDefinition.ISOLATION_READ_UNCOMMITTED))
.execute(new TransactionCallback<Integer>() {
public Integer doInTransaction(TransactionStatus status) {
// update 2
int rows2 = jdbcTemplate.update(...);
return rows2;
}
});
}