сначала покажите код, вот мой код, как показано ниже:
public void saveTestTx() {
Lock lock = new Lock();
lock.setName("ABCDEFG");
lock.setDeviceId("22dfgdfgdftrtg");
lock.setCreateTime((new Date()));
Lock lock1 = lockDao.saveAndFlush(lock);
System.out.println("lock1 = " + lock1);
Lock lock2 = lockDao.findByDeviceId(lock.getDeviceId());
System.out.println("lock2 = " + lock2); // got null here
}
введите описание изображения здесь (вот скриншот)
я уверенчто метод 'saveTestTx ()' является полностью транзакцией, потому что если я вызвал print (22/0), его можно откатить.Я имею в виду, что коды от строки 192 до строки 199 находятся в одной транзакции.Исходя из своего опыта разработки на Java, я думаю, что lock2 - это результат lock1, я знаю, что до печати lock2 транзакция еще не зафиксирована, но они находятся в одной транзакции, видны изменения в той же транзакции, поэтомуперед выполнением транзакции его можно выбрать из вызванного метода «saveAndFlush ()», и оператор вставки будет напечатан на консоли, но на самом деле, почему в lock2 выводится ноль?
myКонфигурация транзакции выглядит следующим образом:
@Configuration
public class TxConfig {
@Bean("txSource")
public TransactionAttributeSource transactionAttributeSource() {
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
readOnlyTx.setReadOnly(true);
readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED,
Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
int isolationLevel = requiredTx.getIsolationLevel();
// requiredTx.setTimeout(90);
Map<String, TransactionAttribute> txMap = new HashMap<>();
txMap.put("init*", requiredTx);
txMap.put("add*", requiredTx);
txMap.put("save*", requiredTx);
txMap.put("insert*", requiredTx);
txMap.put("create*", requiredTx);
txMap.put("persist*", requiredTx);
txMap.put("update*", requiredTx);
txMap.put("modify*", requiredTx);
txMap.put("merge*", requiredTx);
txMap.put("bind*", requiredTx);
txMap.put("delete*", requiredTx);
txMap.put("del*", requiredTx);
txMap.put("drop*", requiredTx);
txMap.put("remove*", requiredTx);
txMap.put("reset*", requiredTx);
txMap.put("cancel*", requiredTx);
txMap.put("login*", requiredTx);
txMap.put("*", readOnlyTx);
source.setNameMap(txMap);
return source;
}
@Bean
public AspectJExpressionPointcutAdvisor pointcutAdvisor(TransactionInterceptor txInterceptor) {
AspectJExpressionPointcutAdvisor pointcutAdvisor = new AspectJExpressionPointcutAdvisor();
pointcutAdvisor.setAdvice(txInterceptor);
// pointcutAdvisor.setExpression("execution (* com.hl..service..*.*(..))");
pointcutAdvisor.setExpression("execution (* com..service..*.*(..)) || execution (* com..dao..*.*(..))");
return pointcutAdvisor;
}
@Bean("txInterceptor")
TransactionInterceptor getTransactionInterceptor(PlatformTransactionManager tx) {
return new TransactionInterceptor(tx, transactionAttributeSource());
}
}
мой код сущности выглядит следующим образом:
@Data
@ToString(callSuper = true)
@Entity
@Table(name = "police_lock")
@SQLDelete(sql = "update lock set is_deleted = 1 where id = ?")
@Where(clause = "is_deleted = 0")
@DynamicInsert
@DynamicUpdate
public class Lock extends LongBaseEntity {
public static interface AddGroup {};
public static interface UpdateGroup {};
private static final long serialVersionUID = 1L;
public Lock() {
super();
}
public Lock(Long id) {
this.id = id;
}
public Lock(boolean isInit) {
super(isInit);
}
@NotBlank(groups = {AddGroup.class,UpdateGroup.class})
private String deviceId;
@NotBlank(groups = {AddGroup.class,UpdateGroup.class})
private String name;
}
моя таблица выглядит следующим образом:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for police_lock
-- ----------------------------
DROP TABLE IF EXISTS `police_lock`;
CREATE TABLE `police_lock` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`device_id` varchar(36) NOT NULL COMMENT 'device_id',
`name` varchar(40) NOT NULL COMMENT 'name',
`create_time` datetime NOT NULL COMMENT 'create_time',
`is_deleted` bit(1) DEFAULT b'0' COMMENT 'is_deleted',
PRIMARY KEY (`id`),
UNIQUE KEY `device_id` (`device_id`)
) ENGINE=InnoDB AUTO_INCREMENT=96 DEFAULT CHARSET=utf8mb4 COMMENT='lock';
метод findByDeviceId () является методом интерфейса jpa данных Spring, достаточно просто определить метод. Это свойство данных jpa пружины, после вызова метода saveAndFlush (), он отправляет sql следующим образом:
Hibernate: insert into police_lock (create_time, is_deleted, device_id, name) values (?, ?, ?, ?)
и после методаизвините, транзакция была зафиксирована, и база данных сгенерировала новую запись.конечно, он не был сгенерирован до того, как метод был оправдан. но мой вопрос таков: хотя он и не зафиксирован, модификация должна быть видна по следующим кодам в той же транзакции, если она не была зафиксирована.но мой не был. Я не знаю почему. .Я что-то здесь упускаю?
мой код находится под загрузкой пружины, данные пружины jpa, mysql.