数据库事务:
JDBC程序中当一个连接对象被创建时,默认情况下是自动提交事务,每次执行一个sql语句时,如果执行成功就会向数据库自动提交,而不能回滚。
JDBC程序中为了让多个sql语句作为一个事务执行。

个人理解的事务,做一件事情,有ABCDE…多个步骤,如果后面的步骤中有无法执行的,那么即使前面做过的ABCD几件事情也要撤销,给恢复成原来没有做过的样子,一件事情要么做就做完,要么就不做,万万不能做一半扔下个烂摊子。

普通买书的过程

Javaweb这本书,单价50元

这本JavaWeb书,单价50元,张飞同学有80元

张飞同学有80元余额

先买一本,书的库存减少,张飞的账户余额减少。

张飞买了一本书,余额剩余30

库存减少一本

张飞剩余30元,这时候他的月不够,但是他尝试买第二本书,这个时候就会出现问题:图书的库存较少了,但是张飞的余额却没有减少,还是30元。

库存又减少一本

但是张飞的余额却没有减少

以下是没有添加事务的程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class TransactionTesr {
/*
* 买书的操作
* 1.每次只能买一本
* 2.更新图书的库存
* 3.减少用户的账户的余额
*/
@Test
public void test() throws Exception {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql:///test";
Connection conn = DriverManager.getConnection(url , "root", "abc123");
//3.写sql语句
String sql = "update book set stock = stock - 1 where isbn = ?";
String sql2 = "update account set balance = balance - ? where id = ?";
//4.预编译sql
PreparedStatement pst = conn.prepareStatement(sql);
//5.填充占位符
pst.setString(1, "10023");
//6.执行sql
pst.executeUpdate();

//预编译
pst = conn.prepareStatement(sql2);
//填充占位符
pst.setDouble(1, 50.00);
pst.setInt(2, 1);
//执行sql
pst.executeUpdate();
conn.close();
pst.close();
}

以下是添加事务的程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
	@Test
public void testTransaction() throws Exception {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql:///test";
Connection conn = DriverManager.getConnection(url , "root", "abc123");
//开启事务
conn.setAutoCommit(false);

PreparedStatement pst = null;
//3.写sql语句
String sql = "update book set stock = stock - 1 where isbn = ?";
String sql2 = "update account set balance = balance - ? where id = ?";
try {
//4.预编译sql
pst = conn.prepareStatement(sql);
//5.填充占位符
pst.setString(1, "10023");
//6.执行sql
pst.executeUpdate();

//预编译
pst = conn.prepareStatement(sql2);
//填充占位符
pst.setDouble(1, 50.00);
pst.setInt(2, 1);
//执行sql
pst.executeUpdate();

//提交事务
conn.commit();
} catch (Exception e) {
conn.rollback();
e.printStackTrace();
}
conn.close();
pst.close();
}

}

添加事务之后,张飞同学的余额不足时候,买书会失败,书的库存不会减少,张飞的月也不会变化。