Spring mvc 创建(可变)Spring安全ACL有一半的时间失败

Spring mvc 创建(可变)Spring安全ACL有一半的时间失败,spring-mvc,transactions,spring-security,acl,Spring Mvc,Transactions,Spring Security,Acl,我使用JDBC支持的SpringSecurity ACL来管理用户创建的对象 我有一个@Service,它处理ACL保护对象的CRUD,因此需要生成适当的ACL并存储它们。我已经将整个类标记为@Transactional,在我的spring-security.xml中配置为 <bean id="oauthTXManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

我使用JDBC支持的SpringSecurity ACL来管理用户创建的对象

我有一个@Service,它处理ACL保护对象的CRUD,因此需要生成适当的ACL并存储它们。我已经将整个类标记为@Transactional,在我的spring-security.xml中配置为

<bean id="oauthTXManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:annotation-driven transaction-manager="oauthTXManager" />
我有一个wee脚本,它测试调用此方法的API。大约有一半的时间我运行脚本时,我在
acl=aclService.createAcl(oi)
处遇到一个错误,创建了acl后,SpringSecurity会尝试将其读回,但找不到它。与中描述的问题非常相似。其他50%的时间,它工作得很好。我能把它缩小到“随机的,大约一半的时间”范围的最好办法是,如果我运行脚本,但它不起作用,然后在超过4秒但不到20秒后再次运行,它就会起作用

奇怪的是,当我检查数据库时,SpringSecurity声称在数据库中找不到的id肯定在那里

我假设我遇到了某种事务或缓存问题。我阅读了的第10.5.6节,但恐怕它并没有真正帮助我确定错误可能在哪里

欢迎任何和所有建议。

我通过同步所有方法来“修复”它,
并且还通过我强制@preauthorized在@Transactional之前进行评估来获得消息

到目前为止,它是有效的

我通过使所有的方法
同步化来“修复”它,并且还通过我强迫@preauthorized在@Transactional之前进行评估来得到消息

到目前为止,它是有效的

@Autowired
@Qualifier("aclService")
private MutableAclService aclService;

...

public Store createNewProfileWithOwner(Store profile, User owner) {
    try {
        Connection con = dataSource.getConnection();
        PreparedStatement query = con.prepareStatement(PROFILE_INSERT);
        ...
        query.executeUpdate();

        Sid sid = new PrincipalSid(owner.getUsername());
        Permission p = BasePermission.ADMINISTRATION;
        ObjectIdentity oi = new ObjectIdentityImpl(profile);
        MutableAcl acl = null;
        try {
            acl = (MutableAcl) aclService.readAclById(oi);
        } catch (NotFoundException e) {
            acl = aclService.createAcl(oi);
        }
        acl.setOwner(sid);
        acl.insertAce(acl.getEntries().size(), p, sid, true);
        aclService.updateAcl(acl);
        profile.setOwner(owner.getUsername());
        ...

    } catch (SQLException e) {
        e.printStackTrace();
    }
    return profile;
}