@Transactional
public interface TransferService {
void transfer(String user1, String user2, double val);
}
通常,不建议在接口上设置@Transactional。但是,对于带有Spring Data的@Repository这样的情况,这是可以接受的。
我们可以将注释放在类定义上,以覆盖接口/超类的事务设置:
@Service
@Transactional
public class TransferServiceImpl implements TransferService {
@Override
public void transfer(String user1, String user2, double val) {
// ...
}
}
现在,通过直接在方法上设置注释来覆盖它:
@Transactional
public void transfer(String user1, String user2, double val) {
// ...
}
3.事务传播
3.1. REQUIRED Propagation
@Transactional(propagation = Propagation.REQUIRED)
public void requiredExample(String user) {
// ...
}
另外,由于默认传播是REQUIRED,因此我们可以通过删除代码来简化代码:
@Transactional
public void requiredExample(String user) {
// ...
}
让我们来看看交易创造是如何工作的伪代码REQUIRED传播:
if (isExistingTransaction()) {
if (isValidateExistingTransaction()) {
validateExisitingAndThrowExceptionIfNotValid();
}
return existing;
}
return createNewTransaction();
3.2. SUPPORTS Propagation
@Transactional(propagation = Propagation.SUPPORTS)
public void supportsExample(String user) {
// ...
}
让我们看看SUPPORTS的事务创建的伪代码:
if (isExistingTransaction()) {
if (isValidateExistingTransaction()) {
validateExisitingAndThrowExceptionIfNotValid();
}
return existing;
}
return emptyTransaction;
3.3. MANDATORY Propagation
@Transactional(propagation = Propagation.MANDATORY)
public void mandatoryExample(String user) {
// ...
}
再看看伪代码
if (isExistingTransaction()) {
if (isValidateExistingTransaction()) {
validateExisitingAndThrowExceptionIfNotValid();
}
return existing;
}
throw IllegalTransactionStateException;
3.4. NEVER Propagation
@Transactional(propagation = Propagation.NEVER)
public void neverExample(String user) {
// ...
}
让我们看一下伪造代码,它说明事务创建如何从不传播:
if (isExistingTransaction()) {
throw IllegalTransactionStateException;
}
return emptyTransaction;
3.5. NOT_SUPPORTED Propagation
Spring首先挂起当前事务(如果存在),然后执行业务逻辑而没有事务。
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void notSupportedExample(String user) {
// ...
}
该JtaTransactionManager中支持实时交易暂停外的开箱。其他人则通过持有对现有引用的引用,然后从线程上下文中将其清除来模拟该悬浮。
3.6. REQUIRES_NEW Propagation
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void requiresNewExample(String user) {
// ...
}
与NOT_SUPPORTED相似,我们需要JTATransactionManager进行实际的事务挂起。
if (isExistingTransaction()) {
suspend(existing);
try {
return createNewTransaction();
} catch (exception) {
resumeAfterBeginException();
throw exception;
}
}
return createNewTransaction();
3.7. NESTED Propagation
@Transactional(propagation = Propagation.NESTED)
public void nestedExample(String user) {
// ...
}
4. Transaction Isolation
4.1. Isolation Management in Spring
if (isolationLevel != ISOLATION_DEFAULT) {
if (currentTransactionIsolationLevel() != isolationLevel) {
throw IllegalTransactionStateException
}
}
现在让我们深入了解不同的隔离级别及其影响。
4.2. READ_UNCOMMITTED Isolation
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void log(String message) {
// ...
}
Postgres不支持READ_UNCOMMITTED隔离,而是回退到READ_COMMITED。另外,Oracle不支持并允许READ_UNCOMMITTED。
4.3. READ_COMMITTED Isolation
@Transactional(isolation = Isolation.READ_COMMITTED)
public void log(String message){
// ...
}
READ_COMMITTED是Postgres,SQL Server和Oracle的默认级别。
4.4. REPEATABLE_READ Isolation
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void log(String message){
// ...
}
REPEATABLE_READ是Mysql中的默认级别。Oracle不支持REPEATABLE_READ。
4.5. SERIALIZABLE Isolation
@Transactional(isolation = Isolation.SERIALIZABLE)
public void log(String message){
// ...
}