首先显示代码,这是我的代码,如下所示:
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()”方法后选择,并在控制台打印insert语句,但事实上,为什么lock2打印为null?
我的交易配置如下:
@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()方法是spring数据jpa接口方法,仅定义一个方法就足够了。这是spring data jpa的特性,在调用saveAndFlush()方法后,它发送如下sql:
Hibernate: insert into police_lock (create_time, is_deleted, device_id, name) values (?, ?, ?, ?)
该方法执行后,提交事务,数据库生成新记录。当然,它不是在方法执行之前生成的。但我的问题是:虽然它没有提交,但修改应该通过同一事务中的以下代码看到,即使它没有提交。但我的不是。我不知道为什么。。我错过什么了吗?
我的代码在Spring boot、Spring data jpa、mysql下。
我现在修复了,我的事务配置有问题,我修改如下:
@Configuration
public class TxConfig2 {
@Autowired
private PlatformTransactionManager transactionManager;
@Bean(name = "txAdvice")
public TransactionInterceptor getAdvisor() throws Exception {
System.out.println("transactionManager = " + transactionManager);
Properties properties = new Properties();
properties.setProperty("init*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("add*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("insert*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("create*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("persist*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("modify*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("merge*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("bind*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("del*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("drop*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("remove*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("reset*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("cancel*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("login*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("save*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("delete*", "PROPAGATION_REQUIRED,-Exception");
properties.setProperty("*", "PROPAGATION_REQUIRED,-Exception,readOnly");
TransactionInterceptor tsi = new TransactionInterceptor(transactionManager, properties);
return tsi;
}
@Bean
public BeanNameAutoProxyCreator txProxy() {
BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
creator.setInterceptorNames("txAdvice");
creator.setBeanNames("*Service","*Dao");
creator.setProxyTargetClass(true);
return creator;
}
}
那么它工作得很好!!!
我面临一个场景,我需要更新参数,并希望在同一事务中检索修改后的值 例如: 我的问题是,我们不能在同一事务中从bean本身检索修改后的值,而不是提交内部事务(即新事务)并从DB中检索它吗?
由于在所述实体不可用的情况下返回,因此需要进行如上所示的条件测试,以避免可能的,否则很可能发生。在任何地方重复这个琐碎的条件测试都是非常不可接受和不鼓励的,这使得业务逻辑应该尽可能简单,几乎不可读。 为了防止这种条件检查到处重复,我在一个单独的EJB中有一个通用方法, 从另一个EJB内部调用此方法,如下所示, 在这里,尽管所有事情都发生在同一个事务中,返回,即返回的实体由两个EJB中的管理。 虽然
问题内容: 我有一张交易表: 并且我希望选择所有特定类型(’R’)的商品,但不要立即(按照date_time字段的顺序)针对同一帐户提交另一种其他类型(’A’)交易的商品… 因此,在给出前面的示例的情况下,查询应引发以下行: (如您所见,第2行未显示,因为第3行“取消了” …第4行也被“第6行“取消了”;第7行出现了(即使帐户003属于已取消的第2行) ,这一次在第7行中不会被任何“ A”行取消;
块将被拒绝 块中的第一个事务将成功,但其余事务将失败 请帮助我了解这个角落的情况。
我试图创建一个环境,在这个环境中设置一个图形用户界面,当用户通过监听器修改它的组件时,另一个线程每隔X秒就向它添加新元素。(这是一个游戏,是的) 我希望游戏在一个类中,而“元素加法器”线程在另一个类中——但Java当然抱怨我无法从另一个线程修改JavaFX GUI。 我见过使用Platform.run稍后()的解决方案,但就我所知,所有这些解决方案都使用匿名内部类。我真的希望我的加法器在另一个(命
(这里的新手垂涎三尺)我一直在寻找将对象(事实)加载到工作内存并通过规则修改它们的方法。根据我目前的发现,我认为我应该在规则结果中使用“修改”指令,但找不到太多关于它的信息。我还遇到了一个使用modifyObject的链接,该链接假定包含2个参数,将旧对象替换为新对象[http://legacy.drools.codehaus.org/Working内存]。 考虑到我使用的是Scala对象(即不可