1

我正在使用 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" />

dataSource是有效的(承诺!),它是一个 Postgres 数据库,如果这可能很重要的话。

所以回到@Service。它看起来像这样(部分):

@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;
}

我有一个小脚本,它测试调用此方法的 API。在我运行脚本的大约一半的时间里,我在创建 ACL SpringSecurity 时会收到一个错误acl = aclService.createAcl(oi),它试图读回它但找不到它。很像这个论坛中描述的问题。其他 50% 的时间它工作得很好。我能把它缩小到“随机,大约一半时间”以上的最好的方法是,如果我运行脚本,但它不起作用,然后在超过 4 秒但不到 20 秒后再次运行,它会工作。

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

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

欢迎任何和所有的建议。

4

1 回答 1

1

我通过制作所有方法来“修复”它,synchronized并且还通过SpringSecurity @Secured 和 @PreAuthorized 提示我强制在 @Transactional 之前评估 @PreAuthrorized。

到目前为止,它有效。

于 2012-12-20T05:14:57.400 回答