1、使用事务
在数据库中使用事务时,必须先开启事务,开启事务的语句如:start transaction;
2、事务开启后就可以执行SQL语句,SQL语句执行成功后,需要相应的语句提交事务,提交事务的语句如:commit;
3、如果不想提交当前事务还可以使用相关语句取消事务,具体语句如:rollback;
4、首先创建一个名称为chapter06的数据库,并且在chapter06中创建一个account表,插入相关的数据,具体操作如下。
5、为了验证数据是否添加成功,可以使用select语句查询account表中的数据,查询结果如下。
可以看出数据添加成功,接下来就可以使用事务来实现转账功能。
6、首先开启事务,然后通过update语句将A账户的100元钱转给B账户,最后提交事务。
7、使用select语句查询account表中的余额,结果如下:
从查询语句可以看出,通过事务成功地完成了转账功能。
8、这时的A账户有900元钱,B账户有1100元钱,开启一个事务,使用update语句实现由B账户向A账户 转100元钱的转账功能;
9、使用select语句来查询account表中的余额,查询结果如:
10、退出数据库后重新登录,并查询数据库中各账户的余额信息
从结果看,事务中的转账操作没有成功,这是因为在事务中转账成功后还没有提交事务就退出数据库了,由于事务中的语句不能自动提交,因此当前的操作就被自动取消了。
11、 再次执行上述语句,然后用commit语句来提交事务。
12、上述语句执行成功后,退出数据库然后再重新登录,使用select语句查询数据库中各账户的余额信息。
从结果可以看出,事务中的转账操作成功了。需要注意的是,由于事务的操作都是手动提交的,因此在操作完事务时,一定要使用commit语句提交事务,否则事务操作失败。
13、这时的A账户有1000元,B账户有1000元,开启一个事务,通过update语句将A账户的100元钱转给B账户。
14、使用select语句查询A账户和B账户的金额。
可以看出转账成功,如果此时A账户不想给B账户转账了,由于事务还没有提交,就可以将事务回滚。
rollback语句执行成功后,再次使用select语句查询数据库,查询结果如;
15、设置B账户中事务的隔离级别
使用select语句查询事务的隔离级别。
B账户:为了证明出现脏读的情况,首先在B账户中开启一个事务,并且该事务中查询当前账户余额信息。
A账户:在A账户中开启一个事务,并且当前窗口中执行转账功能。
需要注意的是,此时不要提交事务,如果提交事务就无法演示出现脏读的情况。
B账户:A账户执行完转账语句后,B账户查询当前账户,此时的查询的结果为:
16、演示不可重复读
B账户:首先在B账户中开启一个事务,然后在当前事务中查询各账户的余额信息。
A账户:在A账户中不用开启事务,直接使用update语句执行更新操作。
由于A账户只需执行修改的操作,不需要保证同步性,因此直接执行SQL语句就可以了。
使用select语句查询A账户的余额信息。
B账户:当A账户中的更新操作执行成功后,在B账户中再次查询各账户的余额。
设置B账户的隔离级别
B账户:在B账户中,重新开启一个事务,然后使用select语句查询当前账户的余额。
此时B账户事务的隔离级别被设置为repeatable read。
验证是否出现不可重复读
B账户:在B账户中,重新开启一个事务,然后使用select语句查询当前账户的余额。
A账户:在A账户中不开启事务,直接使用update语句执行更新操作。
使用select语句查询各账户的余额信息。
B账户:当前A账户中的update语句执行成功后,B账户在当前事务中,再次查询各账户的余额信息。
17、幻读
设置B账户的隔离级别
B账户:由于前面将事务的隔离级别设置为repeatable read(可重复读),这种隔离级别可以避免幻读的出现,因此需要将事务的隔离级别设置得更低,将事务隔离级别设置为read committed。
演示幻读
B账户:首先在B账户中开启一个事务,然后在当前事务中查询账户余额信息。
A账户:在对A账户进行添加操作之前,使用select语句查看当前A账户的信息。
对A账户进行添加操作,A账户不用开启事务,直接执行添加操作。
B账户:当A账户添加记录成功后,可以在B账户中再次查询账户的余额信息。
重新设置B账户的隔离级别
B账户:为了防止出现幻读,可以将B账户的隔离级别设置为repeatable read。
验证是否出现幻读
B账户:在B账户中重新开启一个事务,并在该事务中查询当前账户的余额信息。
A账户:在对A账户进行添加操作之前,使用select语句查看当前A账户的信息。
接下来对A账户进行添加操作,在A账户中不开启事务,直接执行添加操作。
B账户:当A账户的添加操作执行成功后,再次查询当前账户的余额信息。
对比B账户的两次查询结果可以看出,在同一个事务中两次的查询结果是一致的,并没有出现重复读取的情况,因此可以说明当前事务的隔离级别可以避免幻读,最后还需要使用commit语句提交当前事务,提交后的账户查询结果如:
18、可串行化
设置B账户中事务的隔离级别
B账户:首先将B账户的隔离级别设置为serializable。
演示可串行化
B账户:首先在B账户中开启事务,然后使用select语句查询各个账户余额信息。
A账户:开启一个事务,并在该事务中执行插入操作。
提交事务
B账户:当B账户查询完余额信息后,立即提交事务。