事务基本概念
1、事务的基本要素(ACID)
原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节,事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏。比如A向B转账,不可能A扣了钱,B却没收到。
隔离性(lsolaton):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰,比如A正在从一张银行卡中取钱,在A取钱结束前,B不能向这
张卡转账。
持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚.
事务的基本属性包括原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),通常简称为 ACID。在JDBC中,可以使用setAutoCommit(booleam autoCommit)
2、事务井发问题
脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
不可重复读:事务A多次读取同一数据,事务8在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。
幻读:用户A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是用户B就在这个时候插入了一条具体分数的记录,当修改A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
3、MySQL事务隔离机制
mysql默认的事务隔离级别为REPEATABLE-READ,我们可以通过sgI个语句
sql>select@@tx_isotation;
4、jdbc事务原理
JDBC 事务是用来保证数据库的完整性和一致性的机制。在JDBC中,可以通过Conmection 对象来管理事务。
方法来设置是否自动提交事务。如果设置为false,则需要手动调用commit()方法来提交事务,或者调用rol1back()方法来回滚事务。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;public class JDBCTransactionExample {public static void main(String[] args) {Connection conn = null;try {// 加载并注册 JDBC 驱动类Class.forName("com.mysql.cj.jdbc.Driver");// 建立数据库连接conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "username", "password");// 关闭自动提交conn.setAutoCommit(false);// 创建 Statement 对象执行 SQL 语句Statement stmt = conn.createStatement();// 执行 SQL 更新语句stmt.executeUpdate("INSERT INTO mytable (column1) VALUES ('value1')");stmt.executeUpdate("UPDATE mytable SET column1 = 'value2' WHERE column1 = 'value1'");// 提交事务conn.commit();System.out.println("事务成功提交!");} catch (ClassNotFoundException | SQLException e) {try {// 发生异常时回滚事务if (conn != null) {conn.rollback();System.out.println("事务回滚完成!");}} catch (SQLException ex) {ex.printStackTrace();}e.printStackTrace();} finally {try {// 在 finally 块中关闭资源if (conn != null && !conn.isClosed()) {conn.close();}} catch (SQLException ex) {ex.printStackTrace();}}}
}
首先关闭了自动提交事务,然后执行了一系列的 SQL 更新操作。如果这些操作都成功执行,我们会调用 commit()
方法来提交事务。如果在这个过程中发生了异常,我们会捕获异常并调用 rollback()
方法来回滚事务,以保证数据的一致性和完整性。最后,在 finally
块中关闭了数据库连接,释放资源
三、Spring事务机制
1.spring事务管理器
Soing并不直接管理事务,而是提供了多种事务管理器,他们将事务管理委托给Hibemate或者JTA等持久化机制所提供的相关平台框架的事务来实现。通过事务管理器PlatformTransacionManager,Sping为各个平台如JDBC、Hibemate等提供了对应的事务管理器,但是具体的实现依赖各自平台的事务实现。接口代码如下:
public interface PlatformTransactionManager
Transactionstatus getTransaction(TransactionDefinition definition)throws TransactionException;void commit(Transactionstatus status)throws TransactionException,void rollback(TransactionStatus status)throws TransactionException;
2.spring事务定义及状态描述
从事务管理器PlatfomTransactionManager中可以看出,sping完成事务管理还需2个关键元素:事务定义TransacionDefinition及事务状态Transacionstatus描述.
public interface TransactionDefinition{
int getPropagationBehavior();//传播行为,默认PROPAGATION REQUIRED
int getIsolationLevel(); //隔离级别,默认数据库默认级别,如mysql为可重复读
int getTimeout();
boolean isReadonly();//是否只读,查询操作可以设置为true
String getName();
有两个含有事务的方法A和B,B调用A时,A是启用新事务还是延续B的事务,这便是事务传播行为,Spring提供了7种事务传播行为:。PROPAGATION REQUIRED:当前方法必须运行在事务中,如果存在当前事务则加入当前事务,否则开启新事务,spring 默认行为。。PROPAGATION SUPPORTS:当前方法不需要事务上下文,如果存在当前事务则加入当前事务,否则裸奔。PROPAGATION MANDATORY:方法必须在事务中运行,当前事务不存在则报错。
PROPAGATION REQUIRES NEW:方法运行在自己的新事务中。
PROPAGATION NOT SUPPORTED
PROPAGATION NEVER
PROPAGATION NESTED:已存在当前事务则运行在嵌套事务中,否则开启新事务,涉及savepoint。
四、Spring事务的实现方式
编程式事务和声明式事务是sping的2种事务实现方式,其中编程式事务可以直接通过PlatfommTransacionManager来实现,也可以通过TransacionTemplate简单实现,
声明式事务则可以通过xml配置或@Transactional注解方式实现。
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);TransactionStatus status = txManager.getTransaction(definition);
在需要回滚的时候写一下代码
txManager.rollback(status); // 手动事务回滚