ユーザーが作成したオブジェクトを管理するために、JDBC でサポートされた SpringSecurity ACL を使用しています。
ACL で保護されたオブジェクトの CRUD を処理する @Service があるため、適切な 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 DBです。
@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 = aclService.createAcl(oi)
は、ACL を作成した SpringSecurity がスクリプトを読み戻そうとしますが、見つからないというエラーが表示されます。このフォーラムで説明されている問題とよく似ています。残りの 50% の時間は問題なく動作します。「ランダムに、約半分の時間」よりも絞り込むことができる最善の方法は、スクリプトを実行して機能せず、4 秒以上 20 秒以内に再度実行した場合、動作します。
奇妙なことに、DB を確認すると、SpringSecurity が DB で見つからないと主張する ID が確実に存在します。
ある種のトランザクションまたはキャッシュの問題に直面していると思います。Transaction Managementのセクション 10.5.6 を読みましたが、エラーの原因を特定するのにあまり役に立ちませんでした。
どんなアドバイスでも大歓迎です。