一、事务(Transaction)
1、 在开发中我们的一个业务往往需要同时操作多个表,这些操作往往是不可分割,业务中的对数据库的多次操作,要么同时成功,要么全都失败。
2、注意:我们在同一个事务中使用的数据库连接(Connection)必须是同一个。
3、事务的特性(ACID):
1.原子性(atomicity)
一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
2.一致性(consistency)
事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
3.隔离性(isolation)
一个事务的执行不能被其他事务干扰。
即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
4.持久性(durability)
持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
接下来的其他操作或故障不应该对其有任何影响。
4、操作失误的基本步骤:
1.开启事务
- 开启事务以后,我们只后的所有操作将都会在同一个事务当中
2.操作数据库
- 开启事务以后再去操作数据库,所有操作将不会直接提交到数据库中
3.提交事务
- 将修改应用到数据库
4.回滚事务
- 数据库操作过程中出现异常了,回滚事务,回滚事务以后,数据库变成开启事务之前的状态
5、 mysql中的事务控制
#开启事务
START TRANSACTION
#回滚事务
ROLLBACK
#提交事务
COMMIT
6、 JDBC中的事务主要通过Connection对象来控制的
1.开启事务
void setAutoCommit(boolean autoCommit) throws SQLException;
- 设置事务是否自动提交,默认是自动提交
- 设置事务手动提交
conn.setAutoCommit(false);
2.提交事务
void commit() throws SQLException;
- 提交事务
conn.commit()
3.回滚事务
void rollback() throws SQLException;
- 回滚事务
conn.rollback()
二、事务控制
数据访问层的方法用来执行对数据库的操作,为了保证同一个事务中各个原子操作使用的数据库连接(Connection)是同一个,
我们一般在Service层获取数据库连接并传递到dao层
1 public void updateBalance(Connection conn,double money,Integer id) throws SQLException{
2 PreparedStatement ps=null;
3 String sql="update t_money set balance=balance+? where id=?";
4
5 try {
6 ps=conn.prepareStatement(sql);
7 ps.setDouble(1, money);
8 ps.setInt(2, id);
9 ps.executeUpdate();
10 } finally {
11 //在数据访问层,不能关闭数据库连接,必须保持事务的各个原子操作是同一连接
12 JDBCUtils.closeStatement(null, ps);
13 }
14 }
测试代码:
1 @Test
2 public void testTransaction() {
3 Connection conn=null;
4 Dao dao=new Dao();
5 try {
6 conn=JDBCUtils.getConnection(); //获取数据库连接
7 conn.setAutoCommit(false); //组织事务自动提交
8 dao.updateBalance(conn, -100, 1); //原子操作1
9 dao.updateBalance(conn, +100, 2); //原子操作2
10 conn.commit(); //提交事务
11 } catch (Exception e) {
12 e.printStackTrace();
13 try {
14 conn.rollback(); //事务未完整执行成功,回滚
15 } catch (SQLException e1) {
16 e1.printStackTrace();
17 }
18 }
19 }