编程式事务管理是指在代码中显式地管理事务,通常通过Spring的TransactionTemplate或PlatformTransactionManager接口来实现。
示例代码(TransactionTemplate):
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
public class UserService {
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void addUser(User user) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// transactional code
userRepository.save(user);
}
});
}
}
声明式事务管理是通过AOP(Aspect-Oriented Programming)来实现的,通常使用@Transactional注解。
示例代码(注解方式):
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public void addUser(User user) {
userRepository.save(user);
}
}
示例代码(XML配置方式):
在Spring配置文件中配置事务管理器和声明式事务管理:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="*" rollback-for="Exception" />
tx:attributes>
tx:advice>
<aop:config>
<aop:pointcut id="serviceMethods" expression="execution(* com.example.service.*.*(..))" />
<aop:advisor pointcut-ref="serviceMethods" advice-ref="txAdvice" />
aop:config>
Spring事务管理支持多种事务传播行为,这些行为定义了事务方法是如何参与到现有事务中的:
事务隔离级别定义了一个事务与其他事务隔离的程度。Spring支持以下隔离级别:
在MySQL的InnoDB存储引擎中,UPDATE操作主要使用行级锁,具体为排他锁(X锁),以确保数据的一致性和完整性。在较高的隔离级别(如REPEATABLE READ)下,InnoDB还会使用间隙锁或临键锁来防止幻读。这些锁机制确保了在并发环境下,事务能够安全地进行数据修改,而不会导致数据不一致或并发问题。
InnoDB存储引擎支持行级锁和表级锁,但在大多数情况下,它使用行级锁来处理UPDATE操作。
行级锁
行级锁是指锁住单独的行而不是整个表,这种锁可以提高并发性,因为它允许多个事务同时访问同一张表的不同行。InnoDB在执行UPDATE操作时通常使用行级锁,包括以下类型:
在UPDATE操作中,InnoDB通常会使用排他锁(X锁),因为更新操作需要修改数据。
间隙锁(Gap Lock)
间隙锁是InnoDB的一种特殊锁类型,主要用于防止幻读现象。间隙锁锁定一个范围内的所有行,但不锁定实际的行,这对于范围查询和更新操作尤为重要。在某些隔离级别(如REPEATABLE READ)下,InnoDB会使用间隙锁。
临键锁(Next-Key Lock)
临键锁是行锁和间隙锁的组合,锁定一个索引记录及其前面的间隙。这样可以防止插入新的行到已经锁定的范围内,从而避免幻读。
1. 检测行级锁的使用:
INFORMATION_SCHEMA: 可以查询INFORMATION_SCHEMA库中的INNODB_LOCKS和INNODB_TRX表来获取当前锁的信息和事务信息。2.优化行级锁:
3.减少死锁:
SELECT ... FOR UPDATE或SELECT ... LOCK IN SHARE MODE来明确指定锁的行为。