I don't think this is about atomic-operation, synchronization, asynchronous-programming, or transactions.
I think this is about meaningful state.
Right now you have three possible states. The object's uploaded field is true, it's false, or the objects record doesn't exist.
The question then is what do these three states mean? How do we arrive at them? How do we leave them?
I'd like to think we start with the record not existing. Then something decides we need to store a my-object in the DB and now we're uploaded:false. For all I know a decade goes by and then something decides it's time to upload. Since we're still uploaded:false something tries to upload our object. Once the server tells us it has the file we can set uploaded to true.
Now sure anything can happen during all that but there is nothing transactional happening here. We leave uploaded as false until we know it uploaded. If the power cord is yanked out before we manage to flip the bit then we end up thinking we need to upload again. There is no way to stop that.
What we could do is check with the server before uploading and confirm that it needs the file. Or we can blindly overwrite whats there and save the hassle.
What would be silly would be to "roll back" the file upload so we can send it again. All that translates to is having the ability to overwrite the file.
So if those states express everything you need to know then you're fine. Now if you need to do something special or know if an error happened for a good reason like the servers hard drive is full then maybe you want to record more information than true and false somewhere.
Once you decide to do that, think about what you want to do about it.