事务

ACID
原子性
一致性
隔离性
持久性

脏读(dirty read) 一个事务读取了另一个事务尚未提交的数据,
不可重复读(non-repeatable read) 一个事务的操作导致另一个事务前后两次读取到不同的数据
幻读(phantom read) 一个事务的操作导致另一个事务前后两次查询的结果数据量不同。

1, 脏读
一个事务读到另一个事务,尚未提交的修改,就是脏读。
2,不可重复读。
在同一个事务中,再次读取数据时【就是你的select操作】,所读取的数据,和第1次读取的数据,不一样了。就是不可重复读。
3,幻读
事务1读取指定的where子句所返回的一些行。然后,事务2插入一个新行,这个新行也满足事务1使用的查询
where子句。然后事务1再次使用相同的查询读取行,但是现在它看到了事务2刚插入的行。这个行被称为幻象,
因为对事务1来说,这一行的出现是不可思议的。
JDBC定义了五种事务隔离级别:
TRANSACTION_NONE JDBC驱动不支持事务
TRANSACTION_READ_UNCOMMITTED 允许脏读、不可重复读和幻读。
TRANSACTION_READ_COMMITTED 禁止脏读,但允许不可重复读和幻读。
TRANSACTION_REPEATABLE_READ 禁止脏读和不可重复读,单运行幻读。

TRANSACTION_SERIALIZABLE 禁止脏读、不可重复读和幻读。

接口 PlatFormTransactionManager

在这里插入图片描述

package org.springframework.transaction.support;

类 TransactionTemplate

在这里插入图片描述

在这里插入图片描述
注意:用于异常捕获回滚
回滚的底层用的
在这里插入图片描述
rollback

接口 TransactionStatus
在这里插入图片描述

注意:用于单一接口mysql 执行状态判断回滚
如果mysql执行 结果为 0
自己抛一个异常 就全部都回滚了
restModel productMysqlTransactionTemplate.execute(new TransactionCallback()

@Autowired
private TransactionTemplat productMysqlTransactionTemplate;

restModel = productMysqlTransactionTemplate.execute(new TransactionCallback()

doInTransaction(TransactionStatus transactionStatus)

private PlatformTransactionManager transactionManager;
@Override
public T execute(TransactionCallback action) throws TransactionException {
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
}
else {
TransactionStatus status = this.transactionManager.getTransaction(this);
T result;
try {
result = action.doInTransaction(status);
}
catch (RuntimeException ex) {
// Transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
catch (Error err) {
// Transactional code threw error -> rollback
rollbackOnException(status, err);
throw err;
}
catch (Exception ex) {
// Transactional code threw unexpected exception -> rollback
rollbackOnException(status, ex);
throw new UndeclaredThrowableException(ex, “TransactionCallback threw undeclared checked exception”);
}
this.transactionManager.commit(status);
return result;
}
}

public interface CallbackPreferringPlatformTransactionManager extends PlatformTransactionManager {

<T> T execute(TransactionDefinition definition, TransactionCallback<T> callback)
        throws TransactionException;

}

restModel = productMysqlTransactionTemplate.execute(new TransactionCallback() {
@Override
public RestModel doInTransaction(TransactionStatus transactionStatus) {
RestModel restModel1;
//验证行程编号
String tripCode = product.getTrip().getTrip_code();
if(StringUtils.isNotEmpty(tripCode)){
boolean flag = btProductDAO.ifExistTripCode(tripCode);
if(flag){
restModel1 = RestModel.data(ResultStatusEnum.TRAVELNUMBERHASALREADYEXISTED.getStatus(), “行程编号已经存在,不可重复同步。”);
return restModel1;
}
}
//操作产品基础信息表
BTProductMainInfo info = product.getMainInfo();
int homeid = btProductDAO.findHomeAbroad(info.getDestination_city_id());
info.setHome_abroad(homeid);
int vendorCompanyId = btProductDAO.findVendorCompanyId(info.getCreate_user_id());
info.setVendor_company_id(vendorCompanyId);
int flag = btProductDAO.insertProductMainInfo(info);
if (flag == 0) {
restModel1 = RestModel.data(ResultStatusEnum.OPERATIONPRODUCTFAILURE.getStatus(), “产品基础信息添加失败”);
return restModel1;
}
int productId = info.getId();
BTProductSupplementaryInfo supplementaryInfo = product.getSupplementaryInfo();
if (supplementaryInfo != null) {
//新增产品附表
supplementaryInfo.setProduct_id(productId);
btProductDAO.insertProductSupplementaryInfo(supplementaryInfo);
}
//操作线路行程
BTProductTrip trip = product.getTrip();
if (trip != null) {
trip.setProduct_id(productId);
//行程表
btProductDAO.insertProductTrip(trip);
int tripId = trip.getId();
List tripList = trip.getTripDaysList();
if (CollectionUtils.isNotEmpty(tripList)) {
for (BTProductTripDays day : tripList) {
day.setProduct_id(productId);
day.setTrip_id(tripId);
//天表
btProductDAO.insertProductTripDays(day);
int dayId = day.getDay_id();
List chipsList = day.getTripChipsList();
if (CollectionUtils.isNotEmpty(chipsList)) {
for (BTProductTripChips chip : chipsList) {
chip.setDay_id(dayId);
}
//行程段
btProductDAO.insertProductTripChips(chipsList);
}

                            List<BTProductTripShops> shopsList = day.getTripShopsList();
                            if (CollectionUtils.isNotEmpty(shopsList)) {
                                for (BTProductTripShops shop : shopsList) {
                                    shop.setDay_id(dayId);
                                }
                                //行程商店
                                btProductDAO.insertProductTripShops(shopsList);
                            }
                        }
                    }
                }
                restModel1 = RestModel.data(productId);
                return restModel1;
            }
        });
    } catch (Exception e) {
        restModel = RestModel.data(ResultStatusEnum.ERROR.getStatus(), e.getMessage());
    }finally {
        HashMap logMap = new HashMap();
        logMap.put("methodName", "insertProductMainInfo");
        logMap.put("requestId", requestId);
        logMap.put("timeStamp", timeStamp);
        logMap.put("authentication", authentication);
        logMap.put("productInfo", product);
        logMap.put("response", restModel);
        logger.info(JSON.toJSONString(logMap));
    }
    return restModel;
}

2阶段

准备阶段 提交阶段
准备阶段:写redo或者undo日志 锁定资源,执行操作,但并不提交。

提交阶段:告诉准备成功,开始提交,锁定的资源,如何有任何人失败,终止任务,执行undo日志回滚,释放锁定的资源。

3 阶段多了一个询问阶段,减少锁定超时问题

CAP

1.C:Consistency,一致性, 数据一致更新,所有数据变动都是同步的

2.A:Availability,可用性, 好的响应性能,完全的可用性指的是在任何故障模型下,服务都会在有限的时间处理响应

3.P:Partition tolerance,分区容错性,可靠性

任何系统只能满足2点,采用补偿策略达到最终一致性。

BASE

模型包含个三个元素:

1.BA:Basically Available,基本可用

2.S:Soft State,软状态,状态可以有一段时间不同步

3.E:Eventually Consistent,最终一致,最终数据是一致的就可以了,而不是时时保持强一致

TCC

t 执行 c 确认 c 回滚

mysql 5.7 分布式事务 xa 2阶段提交

还是需要业务代码控制

分布式事务通常采用2PC协议,全称Two Phase Commitment Protocol。该协议主要为了解决在分布式数据库场景下,所有节点间数据一致性的问题。在分布式事务环境下,事务的提交会变得相对比较复杂,因为多个节点的存在,可能存在部分节点提交失败的情况,即事务的ACID特性需要在各个数据库实例中保证。总而言之,在分布式提交时,只要发生一个节点提交失败,则所有的节点都不能提交,只有当所有节点都能提交时,整个分布式事务才允许被提交。分布式事务通过2PC协议将提交分成两个阶段,在第一阶段,所有参与全局事务的节点都开始准备(PREPARE),告诉事务管理器它们准备好提交了。在第二阶段,事务管理器告诉资源管理器执行ROLLBACK还是COMMIT。如果任何一个节点显示不能提交,则所有的节点都被告知需要回滚。可见与本地事务不同的是,分布式事务需要多一次的PREPARE操作,待收到所有节点的同意信息后,再进行COMMIT或是ROLLBACK操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值