在计算机系统中,更多的是通过关系型数据库来控制事务,这是利用数据库本身的事务特性来实现的,因此叫数据库事务,由于应用主要靠关系数据库来控制事务,而数据库通常和应用在同一个服务器,所以基于关系型数据库的事务又被称为本地事务。
数据库事务的四大特性 ACID:
A(Atomic):原子性,构成事务的所有操作,要么都执行完成,要么全部不执行,不可能出现部分成功部分失败的情况。
C(Consistency):一致性,在事务执行前后,数据库的一致性约束没有被破坏。比如:张三向李四转100元,转账前和转账后的数据是正确状态这叫一致性,如果出现张三转出100元,李四账户没有增加100元这就出现了数据错误,就没有达到一致性。
I(Isolation):隔离性,数据库中的事务一般都是并发的,隔离性是指并发的两个事务的执行互不干扰,一个事务不能看到其他事务运行过程的中间状态。通过配置事务隔离级别可以避脏读、重复读等问题。
D(Durability):持久性,事务完成之后,该事务对数据的更改会被持久化到数据库,且不会被回滚。
数据库事务在实现时会将一次事务涉及的所有操作全部纳入到一个不可分割的执行单元,该执行单元中的所有操作要么都成功,要么都失败,只要其中任一操作执行失败,都将导致整个事务的回滚
分布式系统会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作,这种分布式系统环境下由不同的服务之间通过网络远程协作完成事务称之为分布式事务。
在 Django 中可以通过django.db.transaction 模块提供的atomic来定义一个事务
from django.db import transaction
@transaction.atomic
def viewfunc(request):
# 这些代码会在一个事务中执行
pass
装饰器用法:整个视图中所有 MySQL 数据库的操作都看做一个事务,范围太大,不够灵活。而且无法直接作用于类视图
from django.db import transaction
def viewfunc(request):
# 这部分代码不在事务中,会被 Django 自动提交
pass
with transaction.atomic():
# 这部分代码会在事务中执行
pass
with 语句用法:可以灵活的有选择性的把某些 MySQL 数据库的操作看做一个事务。而且不用关心视图的类型。
from django.db import transaction
# 创建保存点
save_id = transaction.savepoint()
# 回滚到保存点
transaction.savepoint_rollback(save_id)
# 提交从保存点到当前状态的所有数据库事务操作
transaction.savepoint_commit(save_id)
# 数据库配置
DATABASES = {
"default": {
"ENGINE": "mainsys.mysqlpool",
"NAME": "el_product",
"USER": "select_user",
"PASSWORD": "select_user@321",
"HOST": "10.32",
},
"bt_investment": {
"ENGINE": "mainsys.mysqlpool",
"NAME": "",
"USER": "aaa",
"PASSWORD": "aaa",
"HOST": "10.32",
"ATOMIC_REQUESTS":True
},
"industrychain": {
"ENGINE": "mainsys.mysqlpool",
"NAME": "industrychain",
"USER": "select_user",
"PASSWORD": "select_user@321",
"HOST": "10.32",
},
}
with transaction.atomic(using="bt_investment"): # 指定数据源,可以在python代码的任何位置使用
for obj in execel_data_formart:
@transaction.commit_manually(using='other_db')
@transaction.commit_manually
def test(request):
t3 = model.Test3()
t1 = model.Test1()
try:
sid = transaction.savepoint(using='other_db')
t3.save(using='other_db')
sid1 = transaction.savepoint()
t1.save()
transaction.savepoint_commit(sid,using='other_db')
transaction.commit(using='other_db')
transaction.savepoint_commit(sid1)
transaction.commit()
return rest.response("success")
except:
transaction.savepoint_rollback(sid,using='other_db')
transaction.savepoint_rollback(sid1)
transaction.rollback(using='other_db')
transaction.rollback()
return rest.error_response(400, "fail")