1.什么是事务
事务,一般是指要做的或所做的事情,在计算机术语中是指访问并更新数据库中的各种数据项的一个程序执行单元。事务通常由高级数据库操纵语言或者编程语言书写的用户程序的执行所引起,并形如 begin transaxtion和end transaction 语句来界定,事务由事务开始和事务结束之间的全体操作组成
2.事务的是实现有两种方式
1.编程式事务
将事务管理代码嵌入到业务方法中来控制事务的提交和回滚,在编程式管理事务时,必须在每一个事务操作中包含额外的事务管理代码
2.声明式事务
大多数情况下比编程式事务管理更好用,它将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理,事务管理作为一种横切关注点,可以通过AOP 方法模块化。spring通过AOP框架支持声明事务管理
2.为什么使用事务
update teacher set t_age=t_age-10 where t_name='张三';
1111update teacher set t_age=t_age+10 where t_name='李四';
如果张三向李四转账,中间发生了错误,张三已经转钱了,李四没有收到钱,这不合理---使用事务解决这个问题
--开启事务
BEGIN;
update teacher set t_age=t_age-10 where t_name='刘德华';
1111
--事务回滚
ROLLBACK;
update teacher set t_age=t_age+10 where t_name='黎明';
--事务提交
COMMIT;
当我们的代码从上往下执行的时候,遇见异常会回到刚开始的时候,而且张三减的钱,会到一个缓存区,事务回滚到的时候回到没有减钱的状态,如果我们从上往下执行没有错误的话,会执行提交,一旦提交,那么钱就会发货所能改变
数据库事务的原理
2. 在idea中书写事务--编程式事务
Connection connection =null;
try { Class.forName("com.mysql.cj.jdbc.Driver");
connection= DriverManager.getConnection( "jdbc:mysql://localhost:3306/mydb? serverTimezone=Asia/Shanghai", "root", "root" );
connection.setAutoCommit(false);
//开启事务的 手动提交
String sql = "update tb_emp set salary=salary-1000 where name='金庸'"; PreparedStatement ps = connection.prepareStatement(sql); ps.executeUpdate();
String sql1 = "update tb_emp set salary=salary+1000 where name='张无忌'";
ps = connection.prepareStatement(sql1);
ps.executeUpdate();
connection.commit();
//提交事务
}catch (Exception e){
try {
connection.rollback();
//事务回滚 最初的状 态
} catch (SQLException throwables) { throwables.printStackTrace(); }e.printStackTrace(); }finally{ } } }
3.事务的特性:ACID
1、原子性(Atomicity):
2、一致性(Consistency):
3、隔离性(Isolation):
4、持久性(Durability):
4 .事务的并发问题
1.脏读
事务A读取了事务B更新的数据,然后B 回滚操作,那么A读取到的数据是脏数据
A给B发1000块钱,手一抖打了10000,这个钱已经打到B的户口,但是事务还没有提交,这时B查下卡,发现多了9000,兴奋坏了,但是A及时发现,马上回滚差点提交的事务,将数字改回1000再提交
2.不可重复读
事务A多次读取同一个数据,事务B 在事务A 多次读取的过程中,对数据做了更新并提交,导致事务A 多次读取同一个数据时,结果不一样
3.幻读
已知有两个事务A和B,A从一个表中读取了数据,然后B再该表中插入了一下数据,导致A再次读取同一个表,就会多出几行,简单的说,一个事务先后读取一个范围的记录你,但每次读取的记录数不同,称之为幻读
注意:不可重复读和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除,解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表